#ifndef MAIN_WINDOW_H
#define MAIN_WINDOW_H

#include <gtkmm.h>
#include <libglademm.h>
#include <time.h>

#include <string>

#include <user.h>
#include <singleton.h>
#include <local_log.h>

class MainWindow:public sigc::trackable{
	public:
		MainWindow(){
			xml_interface=Gnome::Glade::Xml::create("ChatServer.glade", "main_window");
			xml_interface->get_widget("main_window", window);
			//initialize LocalLog Singleton to use MainWindow:textview1
			Singleton<LocalLog>::Instance()=LocalLog(this);
			
			
			xml_interface->get_widget("treeview1", user_tree_view);
			user_columns=new UserModelColumns();
			user_ListStore=Gtk::ListStore::create(*user_columns);
			user_tree_view->set_model(user_ListStore);
			user_tree_view->append_column("Email", user_columns->m_col_email);
			user_tree_view->append_column("Status", user_columns->m_col_status);
			
			xml_interface->get_widget("treeview2", message_tree_view);
			message_columns=new MessageModelColumns();
			message_ListStore=Gtk::ListStore::create(*message_columns);
			message_tree_view->set_model(message_ListStore);
			message_tree_view->append_column("Time", message_columns->m_col_time);
			message_tree_view->append_column("Message", message_columns->m_col_message);
		}
		~MainWindow(){}
		void addUser(const User& user){
			Gtk::TreeModel::iterator iter = user_ListStore->append();
			Gtk::TreeModel::Row row = *iter;
			row[user_columns->m_col_email]=user.getEmail().c_str();
		}
		void updateUserStatus(const User& user){
			Gtk::TreeModel::iterator iter = user_ListStore->children().begin();
			for(; iter!=user_ListStore->children().end(); iter++){
				if((*iter)[user_columns->m_col_email]==user.getEmail()){
					(*iter)[user_columns->m_col_status]=user.isOnline()?"Online":"Offline";
				}
			}
		}
		void updateUserStatuses(const std::vector<const User*>& users){
			std::vector<const User*>::const_iterator itr=users.begin();
			for(; itr!=users.end(); ++itr){
				updateUserStatus(**itr);
			}
			//window->queue_draw();
		}
		void removeUser(const User&){
			g_warning("fixme: MainWindow::removeUser()");
		}
		void addMessage(const std::string& message){
			time_t rawtime;
			time ( &rawtime );
			char* c_time=ctime(&rawtime);
			//todo: lock mutex
			Gtk::TreeModel::iterator iter = message_ListStore->append();
			Gtk::TreeModel::Row row = *iter;
			row[message_columns->m_col_time]=c_time;
			row[message_columns->m_col_message]=message.c_str();
			//todo: unlock mutex
			
			//window->queue_draw();
		}
	private:
		class UserModelColumns : public Gtk::TreeModelColumnRecord{
			public:
				UserModelColumns(){ add(m_col_email); add(m_col_status); }
				Gtk::TreeModelColumn<Glib::ustring> m_col_email;
				Gtk::TreeModelColumn<Glib::ustring> m_col_status;
		};
		class MessageModelColumns : public Gtk::TreeModelColumnRecord{
			public:
				MessageModelColumns(){ add(m_col_time); add(m_col_message); }
				Gtk::TreeModelColumn<Glib::ustring> m_col_time;
				Gtk::TreeModelColumn<Glib::ustring> m_col_message;
		};
		Glib::RefPtr<Gnome::Glade::Xml> xml_interface;
		Gtk::Window* window;
		Gtk::TreeView* user_tree_view;
		UserModelColumns* user_columns;
		Glib::RefPtr<Gtk::ListStore> user_ListStore;
		Gtk::TreeView* message_tree_view;
		MessageModelColumns* message_columns;
		Glib::RefPtr<Gtk::ListStore> message_ListStore;
};

void LocalLog::send(const std::string& s){
	if(main_window){
		main_window->addMessage(s);
	}
}
#endif
